
package cz.czu.pef.DataModelling.dao.impl;

import java.util.*;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.*;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import cz.czu.pef.DataModelling.dao.DataModellingDao;
import cz.czu.pef.DataModelling.utils.Constants;


@Repository(value = "dataModellingDao")
@Transactional
@Configurable
public class DataModellingDaoImpl implements DataModellingDao
{

  private static final Logger logger = Logger.getLogger(DataModellingDaoImpl.class.getName());

  public DataModellingDaoImpl()
  {
  }

  @PersistenceContext
  private EntityManager entityManager;

  public void setEntityManager(EntityManager entityManager)
  {
    this.entityManager = entityManager;
  }

  public EntityManager getEntityManager()
  {
    return this.entityManager;
  }

  private Session getHibernateSession()
  {
    // http://stackoverflow.com/questions/4148231/how-can-i-get-the-session-object-if-i-have-the-entitymanager
    //org.hibernate.Session session = (Session) entityManager.getDelegate(); // JPA 1.0 spec
    //org.hibernate.Session session = (Session) entityManager.unwrap(Session.class); // JPA 2.0 spec
    return entityManager.unwrap(Session.class); // JPA 2.0 spec style
  }

  /**
   * Create HQL query for usage by Daos (mainly mapping arguments etc...)
   *
   * @param hql
   * @return Query object suitable for HQL queries
   */
  protected Query createHqlQuery(final String hql)
  {
    if (logger.isLoggable(Level.INFO))
    {
      logger.info("createHqlQuery - going to create hql query: " + hql);
    }
    return getHibernateSession().createQuery(hql);
  }

  /**
   * Create SQL query for usage by Daos (mainly mapping arguments etc...)
   *
   * @param sql
   * @return Query object suitable for SQL queries
   */
  protected SQLQuery createSqlQuery(final String sql)
  {
    if (logger.isLoggable(Level.INFO))
    {
      logger.info("createSqlQuery - going to create sql query: " + sql);
    }
    return getHibernateSession().createSQLQuery(sql);
  }

  /**
   * Executes HQL or SQL query
   *
   * @param query
   * @return List of entities, or arrays, as defined by HQL
   */
  protected Object executeQuery(final Query query)
  {
    if (logger.isLoggable(Level.INFO))
    {
      logger.info("executeHql - executing HQL: " + query.getQueryString());
    }
    return query.list();
  }


  @SuppressWarnings("unchecked")
  @Override
  public List<Object[]> getAllMissingTrainings()
  {
    return createHqlQuery(Constants.missingTrainingsHqlSelect).list();
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Object[]> getAllMissingMedicalExaminations()
  {
    return createHqlQuery(Constants.missingMedicalExaminationsHqlSelect).list();
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Object[]> getAllMachineryWorkers()
  {
    return createHqlQuery(Constants.selectAllMachineryWorkers).list();
  }
}
